package com.dsideal.cloud.cas.client.controller;

import com.alibaba.fastjson.JSONObject;
import com.dsideal.cloud.annotation.DsidealLog;
import com.dsideal.cloud.auth.core.annotation.IgnoreUserToken;
import com.dsideal.cloud.auth.suzhou.entity.UserEntity;
import com.dsideal.cloud.auth.suzhou.response.SuzhouResponse;
import com.dsideal.cloud.auth.suzhou.service.SuzhouAuthService;
import com.dsideal.cloud.cas.client.cache.RedisUserCache;
import com.dsideal.cloud.cas.client.constant.LoginConstants;
import com.dsideal.cloud.cas.client.dto.UserDetailsDTO;
import com.dsideal.cloud.cas.client.entity.RestLogin;
import com.dsideal.cloud.cas.client.entity.TokenEntity;
import com.dsideal.cloud.cas.client.entity.UserLog;
import com.dsideal.cloud.cas.client.manager.LoginManager;
import com.dsideal.cloud.cas.client.utils.JwtTokenUtil;
import com.dsideal.cloud.common.constant.BusinessType;
import com.dsideal.cloud.common.constant.ErrorCode;
import com.dsideal.cloud.common.log.DsLogger;
import com.dsideal.cloud.common.response.BaseResponse;
import com.dsideal.cloud.common.response.ObjectRestResponse;
import com.dsideal.cloud.common.spring.SpringContextUtil;
import com.dsideal.cloud.common.util.DateUtils;
import com.dsideal.cloud.common.util.IpUtils;
import com.dsideal.cloud.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 苏州登录类
 *
 * @author suny
 */
@Controller
@RequestMapping("/sz")
@IgnoreUserToken
public class SuzhouLoginController {

    private final static DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static final DsLogger log = DsLogger.buildLogger(SuzhouLoginController.class);

    @Autowired
    SuzhouAuthService service;

    @Autowired
    private RedisUserCache redisUserCache;

    @Autowired
    private LoginManager loginManager;

    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Value("${auth.suzhou.redirectUrl}")
    private String redirectUrl;

    @Value("${mainUrl}")
    private String mainUrl;

    @Value("${jwt.expire}")
    private String expire;

    final static String SUCCESS_CODE = "000000";
    final static String SUCCESS_DESC = "api sucess!";
    final static Integer SUCCESS_FLAG = 1;

    @GetMapping({"/index"})
    public String loginSz(String username) {
        UserDetailsDTO userDetailsDTO = loginManager.extendUserInfo(username);
        Integer flag;
        String token=StringUtils.EMPTY;
        if(userDetailsDTO!=null){
            flag=SUCCESS_FLAG;
            token = loginManager.createToken(userDetailsDTO, jwtTokenUtil.web);
            redisUserCache.putTokenInCache("web" + userDetailsDTO.getUserId(), token);
        }else {
            flag= ErrorCode.USER_NOT_EXIST.value();
        }
        String returnUrl = "redirect:" + redirectUrl + "?authorization=" + token + "&expire=" + expire+"&flag=" + flag;
        return returnUrl;
    }

    @GetMapping({"/plus"})
    @DsidealLog(title = "苏州web端用户登录",businessType = BusinessType.LOGIN)
    public String loginSzPlus(String yjUserId, String yjToken, String extId) {
        long start = System.currentTimeMillis();
        log.info("**********************{} 进入登录方法，用户ID={} **********************",
                df.format(new Date()), yjUserId);
        UserDetailsDTO userDetailsDTO = loginManager.extendUserInfoById(yjUserId);
        Integer flag;
        String token = StringUtils.EMPTY;
        if (userDetailsDTO != null) {
            flag = SUCCESS_FLAG;
            token = loginManager.createToken(userDetailsDTO, jwtTokenUtil.web);
            redisUserCache.putTokenInCache("web" + userDetailsDTO.getUserId(), token);

            //记录ip
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String loginIp = IpUtils.getIpAddress(request);
            //登录成功，此时记录登录成功日志
            UserLog userSuccessLog = UserLog.builder().baseUserId(userDetailsDTO.getUserId())
                    .loginType(LoginConstants.LoginType.ACCOUNT_PASSWORD.getCode())
                    .accountType(LoginConstants.AccountType.NORMAL_ACCOUNT.getCode())
                    .equipmentType(LoginConstants.EquipmentType.WEBPAGE.getCode())
                    .loginResult(LoginConstants.LoginResult.SUCCESS.getCode())
                    .loginIp(loginIp)
                    .build();

            loginManager.insertUserLog(userSuccessLog);
        } else {
            flag = ErrorCode.USER_NOT_EXIST.value();
            //登录失败，此时记录登录失败日志   todo  失败的时候，没有了用户id，无法进行记录
            /*UserLog userSuccessLog = UserLog.builder().baseUserId(userDetailsDTO.getUserId())
                    .loginType(LoginConstants.LoginType.ACCOUNT_PASSWORD.getCode())
                    .accountType(LoginConstants.AccountType.NORMAL_ACCOUNT.getCode())
                    .equipmentType(LoginConstants.EquipmentType.WEBPAGE.getCode())
                    .loginResult(LoginConstants.LoginResult.FAIL.getCode())
                    .loginRemark(ErrorCode.USER_NOT_EXIST.message())
                    .build();
            loginManager.insertUserLog(userSuccessLog);*/
        }
        log.info("登录用户的互动角色id是=====>{}", extId);
        loginManager.updateUserYjToken(yjUserId, yjToken, extId);
//        String returnUrl = "redirect:" + redirectUrl + "?authorization=" + token + "&expire=" + expire;
        String returnUrl = "redirect:" + redirectUrl + "?authorization=" + token + "&expire=" + expire+"&flag=" + flag;
        log.info("**********************{} 登录方法结束，用户ID={} ,耗时{}秒**********************",
                df.format(new Date()), yjUserId, (int)((System.currentTimeMillis()-start)/1000));
        return returnUrl;
    }

    @GetMapping({"/plus/tp"})
    @DsidealLog(title = "苏州web端用户登录",businessType = BusinessType.LOGIN)
    @ResponseBody
    public BaseResponse loginSzPlusTp(String yjUserId, String yjToken, String extId) {
        long start = System.currentTimeMillis();
        log.info("**********************{} 进入登录方法，用户ID={}，线程={} **********************",
                df.format(new Date()), yjUserId, Thread.currentThread().getName());
        UserDetailsDTO userDetailsDTO = loginManager.extendUserInfoById2(yjUserId);
        String token = loginManager.createToken(userDetailsDTO, jwtTokenUtil.web);
        redisUserCache.putTokenInCache("web" + userDetailsDTO.getUserId(), token);
        log.info("**********************{} 要加的日志，用户ID={} ,耗时{}秒，线程={}**********************",
                df.format(new Date()), yjUserId, (int)((System.currentTimeMillis()-start)/1000), Thread.currentThread().getName());
//        loginManager.updateUserYjToken(yjUserId, yjToken, extId);
        String returnUrl = "redirect:" + redirectUrl + "?authorization=" + token + "&expire=" + expire;
        log.info("**********************{} 登录方法结束，用户ID={} ,耗时{}秒，线程={}**********************",
                df.format(new Date()), yjUserId, (int)((System.currentTimeMillis()-start)/1000), Thread.currentThread().getName());
        return BaseResponse.ok();
    }

    /**
     * 苏州接口登录方法
     * 1-8新增了域账号登录方式
     * @param userInfo
     * @return
     */
    @PostMapping("/login/restful")
    @ResponseBody
    public ObjectRestResponse<TokenEntity> loginRestful(@RequestBody RestLogin userInfo) {
        SuzhouResponse response = null;
        if ("domain".equals(userInfo.getType())) {
            response = service.loginDomain(userInfo.getUsername(), userInfo.getPassword(), userInfo.getCaptchaKey(), userInfo.getCaptchaValue());
        } else {
            response = service.login(userInfo.getUsername(), userInfo.getPassword(), userInfo.getCaptchaKey(), userInfo.getCaptchaValue());
        }
        JSONObject result = JSONObject.parseObject(response.getBodyContent());
        String retCode = result.getString("retCode");
        String retDesc = result.getString("retDesc");
        UserEntity user = result.getObject("data", UserEntity.class);
        if (user == null || StringUtils.isBlank(user.getUserId())) {
            return BaseResponse.error(Integer.parseInt(retCode), retDesc,
                    ObjectRestResponse.class);
        }
//        if (SUCCESS_CODE.equals(retCode) && SUCCESS_DESC.equals(retDesc)) {
//            UserEntity user = result.getObject("data", UserEntity.class);
            UserDetailsDTO userDetailsDTO = loginManager.extendUserInfoById(user.getUserId());
            if (userDetailsDTO == null || StringUtils.isBlank(userDetailsDTO.getUserId())) {
                return BaseResponse.error(ErrorCode.USER_NOT_EXIST, ObjectRestResponse.class);
            }
            //由于入参以及出参都没有基础库用户id，添加方法记录，避免内部调用aop失效,手动获取代理对象调用 ==============
            SuzhouLoginController suzhouLoginController = SpringContextUtil.getBean(SuzhouLoginController.class);
            suzhouLoginController.restfulLog(user.getUserId(),userInfo);

            String token = loginManager.createToken(userDetailsDTO, userInfo.getCode());
            redisUserCache.putTokenInCache(userInfo.getCode() + userDetailsDTO.getUserId(), token);

            //记录ip
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String loginIp = IpUtils.getIpAddress(request);
            //登录成功，此时记录登录成功日志
            UserLog userSuccessLog = UserLog.builder().baseUserId(userDetailsDTO.getUserId())
                    .loginType(userInfo.getLoginType())
                    .accountType("domain".equals(userInfo.getType()) ? LoginConstants.AccountType.DOMAIN_ACCOUNT.getCode() : LoginConstants.AccountType.NORMAL_ACCOUNT.getCode())
                    .equipmentType(userInfo.getEquipmentType())
                    .loginResult(LoginConstants.LoginResult.SUCCESS.getCode())
                    .loginIp(loginIp)
                    .build();
            loginManager.insertUserLog(userSuccessLog);
            String yjRoleIds = "";
            if (user.getUserExtList() != null && user.getUserExtList().length > 0) {
                yjRoleIds = Arrays.stream(user.getUserExtList()).map(i -> i.getUserExtId()).collect(Collectors.joining(","));
            }
            loginManager.updateUserYjToken(user.getUserId(), user.getAccessToken(), yjRoleIds);
            return ObjectRestResponse.ok(new TokenEntity(expire, token));
//        }
//
//        return BaseResponse.error(Integer.parseInt(retCode), retDesc,
//                ObjectRestResponse.class);
    }

    /**
     * @Author zw
     * @Description 记录域账号登录时候的的基础库用户id信息
     * @Date 上午 9:54 2021/2/18
     * @Param [yjUserId, userInfo]
     * @return void
     **/
    @DsidealLog(title = "苏州移动端/客户端用户登录",businessType = BusinessType.LOGIN)
    public void restfulLog(String yjUserId,RestLogin userInfo){
        log.info("restful登录，基础库用户id是=====>{}", yjUserId);
    }


    /**
     * @return
     */
    @PostMapping("/login/add")
    @ResponseBody
    public ObjectRestResponse loginAdd() throws Exception {
        List<Map<String, Object>> loginList = loginManager.login();
        //return ObjectRestResponse.ok(StringUtils.EMPTY);
        for(Map<String, Object> a : loginList) {
            UserDetailsDTO userDetailsDTO = loginManager.extendUserInfoById(a.get("yjUser").toString());
            if (userDetailsDTO == null || StringUtils.isBlank(userDetailsDTO.getUserId())) {
                continue;
            }
            //登录成功，此时记录登录成功日志
            UserLog userSuccessLog = UserLog.builder().baseUserId(userDetailsDTO.getUserId())
                    .loginType("1")
                    .accountType(LoginConstants.AccountType.NORMAL_ACCOUNT.getCode())
                    .equipmentType(LoginConstants.EquipmentType.WEBPAGE.getCode())
                    .loginResult(LoginConstants.LoginResult.SUCCESS.getCode())
                    .loginIp(StringUtils.EMPTY)
                    .createTime(DateUtils.parseDate(a.get("createTime").toString(),DateUtils.YYYY_MM_DD_HH_MM_SS))
                    .build();
            loginManager.insertUserLog(userSuccessLog);
        };
        return ObjectRestResponse.ok(StringUtils.EMPTY);

    }
}
